/**
 * JAVACC DEMO 1.0
 */
package com.apache.client.servlet;

import com.apache.api.vo.ResultEntity;
import com.apache.api.vo.ResultMsg;
import com.apache.client.LogClient;
import com.apache.client.UctCoreClient;
import com.apache.passport.common.DesUtils;
import com.apache.passport.common.PassportHelper;
import com.apache.passport.entity.Token;
import com.apache.rpc.common.LoadRpcService;
import com.apache.tools.MD5Utils;
import com.apache.tools.OsUtils;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.ToolsUtil;
import com.apache.uct.common.entity.User;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.*;

/**
 * description:  用户中心客户端统一servlet
 *
 * @author ius 创建时间：2016-10-28
 */
@SuppressWarnings("serial")
public class UctClientServlet extends HttpServlet {

    private Logger log = LoggerFactory.getLogger(UctClientServlet.class);

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    /**
     * description:  注册时在请求参数中加doCode=regUser;
     * 修改用户信息时在请求参数中加doCode=editUser
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String doCode = request.getParameter("doCode");
        if (StrUtil.isNull(doCode)) {
            JSONObject json = new JSONObject();
            json.put("flag", "F");
            json.put("msg", "请求非法,访问终止");
            outputJson(json.toString(), response);
            return;
        }
        try {
            Method method = UctClientServlet.class.getDeclaredMethod(doCode,
                    new Class[] { HttpServletRequest.class, HttpServletResponse.class });
            method.invoke(this, request, response);
        } catch (Exception e) {
            log.error("异常",e);
            JSONObject json = new JSONObject();
            json.put("flag", "F");
            json.put("msg", "系统执行异常,请稍后重试");
            outputJson(json.toString(), response);
        }
    }

    /**
     * description:  登录成功后跳转页面
     */
    public void gotoIndex(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String path = request.getContextPath();
        String csetUrl = request.getScheme() + "://" + request.getServerName() + ":" + request
                .getServerPort() + path;
        //要跳转到哪个url
        String gotoURL = request.getParameter("go");
        if (StrUtil.isNull(gotoURL)) {
            gotoURL = csetUrl;
        } else {
            if (gotoURL.startsWith(path)) {
                gotoURL = request.getScheme() + "://" + request.getServerName() + ":" + request
                        .getServerPort() + gotoURL;
            }
        }
        //自定义登录页面
        String login_url = ToolsUtil.getInstance().getValueByKey("uct_server");
        //获取系统名称
        String tokenId = String.valueOf(request.getSession().getAttribute("tokenId"));
        String reqParams = "";
        if ("T".equals(ToolsUtil.getInstance().getValueByKey("is_url_params"))) {
            reqParams = PassportHelper.getInstance().getReqParams(request, "doCode,go");
            reqParams = PassportHelper.getInstance().isNov(reqParams, reqParams, "?" + reqParams);
        }
        ArrayList<String> lst = new ArrayList<String>();
        StringBuffer tokenUrl = new StringBuffer();
        lst.add(login_url);
        lst.add(tokenId);
        lst.add(gotoURL + reqParams);
        lst.add("iussoft");
        lst.add(csetUrl);
        Collections.sort(lst);
        String sha1Rtn = PassportHelper.getInstance().SHA1(lst);
        //是否使用统一登录系统登录 T/F
        String login_pass = ToolsUtil.getInstance().getValueByKey("login.pass");
        if ("T".equals(login_pass)) {
            //如果cookie为空,则跳转到登录页面
            tokenUrl.append(login_url);
            tokenUrl.append("?");
            tokenUrl.append("ptlang=" + sha1Rtn);
            tokenUrl.append("&");
            tokenUrl.append("tokenId=" + tokenId);//设置远程cookie
            tokenUrl.append("&");
            tokenUrl.append("go=" + gotoURL + reqParams);
            tokenUrl.append("&");
            tokenUrl.append("cset=" + csetUrl);
        } else {
            tokenUrl.append(login_url);
        }
        response.sendRedirect(tokenUrl.toString());
    }

    /**
     * description:  用户登录方法
     */
    public void login(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        ResultMsg msg = new ResultMsg("F", "登录失败");
        Map<String, String> params = getParameterMap(request);
        Map<String, Object> maps = new HashMap<String, Object>();
        if (StrUtil.isNull(params.get("username")) || StrUtil.isNull(params.get("password"))) {
            msg = new ResultMsg("F", "用户名或密码不能为空");
            outputJson(JSONObject.fromObject(msg).toString(), response);
            return;
        }
        String sysEname = ToolsUtil.getInstance().getValueByKey("sysEname");
        maps.put("userEname", params.get("username"));
        maps.put("userPass", params.get("password"));
        maps.put("sysEname", sysEname);
        maps.put("addressIP", request.getRemoteAddr());
        ResultEntity entity = LoadRpcService.service()
                .dubboServiceClient("ssoService", "outSideSocketLoginService", maps);
        if (("true".equals(entity.getResult())) && !ToolsUtil.isEmpty(entity.getEntity())) {
            if (entity.getEntity() instanceof String) {
                msg.setMsg(String.valueOf(entity.getMessage()));
            } else {
                Token token = (Token) entity.getEntity();
                //				Cookie cookie = new Cookie("ius_", token.getTokenId());
                //				cookie.setPath("/");
                //				cookie.setMaxAge(-1);
                //				Cookie ucsso = new Cookie("_uc.sso", token.getUserEname());
                //				ucsso.setPath("/");
                //				ucsso.setMaxAge(-1);
                //				response.addCookie(cookie);
                //				response.addCookie(ucsso);
                request.getSession().removeAttribute("loginUser");
                request.getSession().removeAttribute("tokenId");
                request.getSession().setAttribute("tokenId", token.getTokenId());
                msg = new ResultMsg("T", "登录成功");

                Map<String, Object> logMap = new HashMap<String, Object>();
                logMap.put("logOperationType", "login");
                logMap.put("logClassName", User.class.getName());
                logMap.put("logIp", getLocalIp());
                logMap.put("log_userEname", DesUtils.getInstance().decrypt(token.getUserEname()));
                LogClient.getInstance().execute(logMap);//添加日志
            }
        }
        outputJson(JSONObject.fromObject(msg).toString(), response);
    }

    /**
     * description:  修改用户信息
     */
    public void editUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        ResultMsg msg = new ResultMsg("F", "信息修改失败");
        Map<String, String> params = getParameterMap(request);
        String username = StrUtil.doNull(params.get("username"), "");
        String realname = StrUtil.doNull(params.get("realname"), "");
        String password = StrUtil.doNull(params.get("password"), "");
        String email = StrUtil.doNull(params.get("email"), "");
        String checkUserPass = StrUtil.doNull(params.get("checkUserPass"), "0");
        try {
            if ("1".equals(checkUserPass)) {
                String password2 = StrUtil.doNull(params.get("password2"), "");
                String oldpassword = StrUtil.doNull(params.get("oldpassword"), "");
                if (!password.equals(password2)) {
                    msg = new ResultMsg("F", "两次密码输入不一致");
                    outputJson(JSONObject.fromObject(msg).toString(), response);
                    return;
                }
                if (StrUtil.isNull(oldpassword)) {
                    msg = new ResultMsg("F", "旧密码不能为空");
                    outputJson(JSONObject.fromObject(msg).toString(), response);
                    return;
                }
                oldpassword = MD5Utils.crypt(oldpassword);
                LoginUser loginUser = (LoginUser) request.getSession().getAttribute("loginUser");
                if (!oldpassword.equals(loginUser.getUserPass())) {
                    msg = new ResultMsg("F", "旧密码输入的不正确");
                    outputJson(JSONObject.fromObject(msg).toString(), response);
                    return;
                }
            }
            Map<String, Object> map = new HashMap<String, Object>();
            if (StrUtil.isNotNull(params.get("userid"))) {
                map.put("userId", params.get("userid"));
            }
            if (StrUtil.isNotNull(username))
                map.put("userEname", username);
            if (StrUtil.isNotNull(realname))
                map.put("userCname", realname);
            if ("1".equals(checkUserPass)) {
                if (StrUtil.isNull(password)) {
                    msg = new ResultMsg("F", "密码不能为空");
                    outputJson(JSONObject.fromObject(msg).toString(), response);
                    return;
                }
                password = MD5Utils.crypt(password);
                map.put("userPass", password);
            }
            if (StrUtil.isNotNull(email))
                map.put("email", email);
            if (StrUtil.isNotNull(params.get("phone")))
                map.put("phone", params.get("phone"));
            if (StrUtil.isNotNull(params.get("mobile")))
                map.put("mobile", params.get("mobile"));
            ResultEntity entity = UctCoreClient.editUserInfo(map);
            if (("true".equals(entity.getResult())) && !ToolsUtil.isEmpty(entity.getEntity())) {
                logInfo("edit", username, map);
                msg = new ResultMsg("T", "信息修改成功");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        outputJson(JSONObject.fromObject(msg).toString(), response);
    }

    /**
     * description:  用户注册
     */
    public void regUser(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        ResultMsg msg = new ResultMsg("F", "注册失败");
        Map<String, String> params = getParameterMap(request);
        if (StrUtil.isNull(params.get("username"))) {
            msg = new ResultMsg("F", "用户名不能为空");
            outputJson(JSONObject.fromObject(msg).toString(), response);
            return;
        }
        if (StrUtil.isNull(params.get("password"))) {
            msg = new ResultMsg("F", "密码不能为空");
            outputJson(JSONObject.fromObject(msg).toString(), response);
            return;
        }
        if (StrUtil.isNull(params.get("password2"))) {
            msg = new ResultMsg("F", "密码不能为空");
            outputJson(JSONObject.fromObject(msg).toString(), response);
            return;
        }
        if (!params.get("password").equals(params.get("password2"))) {
            msg = new ResultMsg("F", "两次密码不一致");
            outputJson(JSONObject.fromObject(msg).toString(), response);
            return;
        }
        if (StrUtil.isNull(params.get("realname"))) {
            msg = new ResultMsg("F", "真实姓名不能为空");
            outputJson(JSONObject.fromObject(msg).toString(), response);
            return;
        }
        try {
            ResultEntity entity = null;
            Map<String, Object> map = new HashMap<String, Object>();
            String realname = java.net.URLDecoder.decode(params.get("realname"), "UTF-8");
            map.put("userEname", params.get("username"));
            map.put("userPass", MD5Utils.crypt(params.get("password")));
            map.put("userCname", realname);
            if (ToolsUtil.isNotNull(params.get("email")))
                map.put("email", params.get("email"));
            if (ToolsUtil.isNotNull(params.get("mobile")))
                map.put("mobile", params.get("mobile"));
            String orgcname = params.get("orgcname");
            if (StrUtil.isNotEmpty(orgcname)) {
                orgcname = java.net.URLDecoder.decode(orgcname, "UTF-8");
            }
            String sysEname = ToolsUtil.getInstance().getValueByKey("sys_ename");//系统名称
            map.put("sysEname", sysEname);
            if (ToolsUtil.isNotNull(params.get("usertype")))
                map.put("userType", params.get("usertype"));
            if (ToolsUtil.isNotNull(params.get("phone")))
                map.put("phone", params.get("phone"));
            map.put("orgEname", params.get("orgename"));
            if (ToolsUtil.isNotNull(params.get("orgcname")))
                map.put("orgCname", orgcname);
            if (ToolsUtil.isNotNull(params.get("company")))
                map.put("company", params.get("company"));
            if (ToolsUtil.isNotNull(params.get("usersex")))
                map.put("userSex", params.get("usersex"));
            if (ToolsUtil.isNotNull(params.get("actFullEname")))
                map.put("actFullEname", params.get("actFullEname"));
            map.put("userStatus", StrUtil.doNull(params.get("userstatus"), "1"));
            if (!StrUtil.isNull(params.get("province"))) {
                map.put("province", params.get("province"));
            }
            if (!StrUtil.isNull(params.get("city"))) {
                map.put("city", params.get("city"));
            }
            entity = UctCoreClient.saveUserInfo(map);
            if (("true".equals(entity.getResult())) && !ToolsUtil.isEmpty(entity.getEntity())) {
                map.put("userId", entity.getEntity());
                logInfo("save", params.get("username"), map);
                msg = new ResultMsg("T", "注册成功");
            } else {
                msg = new ResultMsg("F", StrUtil.doNull(entity.getMessage(), "注册失败"));
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
        outputJson(JSONObject.fromObject(msg).toString(), response);
    }

    /**
     * 输出json数据
     */
    protected void outputJson(String json, HttpServletResponse response) throws IOException {
        if (StrUtil.isNotNull(json)) {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            out.print(json);
            out.flush();
            out.close();
        }
    }

    /**
     * description:  获取请求参数
     */
    @SuppressWarnings("rawtypes")
    protected Map<String, String> getParameterMap(HttpServletRequest request) {
        Map<String, String> map = new HashMap<String, String>();
        Set keSet = request.getParameterMap().entrySet();
        for (Iterator itr = keSet.iterator(); itr.hasNext(); ) {
            Map.Entry me = (Map.Entry) itr.next();
            Object ok = me.getKey();
            if ("doCode".equalsIgnoreCase(ok.toString()))
                continue;
            Object ov = me.getValue();
            String[] value = new String[1];
            if (ov instanceof String[]) {
                value = (String[]) ov;
            } else {
                value[0] = ov.toString();
            }
            if (value.length > 0) {
                map.put(ok.toString(), value[0]);
            }
        }
        return map;
    }

    /**
     * description:  添加审计
     */
    private void logInfo(String logType, String userEname, Map<String, Object> map) {
        Map<String, Object> logMap = new HashMap<String, Object>();
        logMap.put("logType", logType);
        logMap.put("logClassName", User.class.getName());
        logMap.put("logIp", getLocalIp());
        logMap.put("log_userEname", userEname);
        logMap.putAll(map);
        LogClient.getInstance().execute(logMap);//添加日志
    }

    /**
     * 获取本机ip地址
     *
     * @return 返回本机的IP地址
     */
    public String getLocalIp() {
        String localIp = "127.0.0.1";
        try {
            if ("linux".equals(OsUtils.getSystemType())) {
                Enumeration<NetworkInterface> netInterfaces = null;
                try {
                    netInterfaces = NetworkInterface.getNetworkInterfaces();
                    while (netInterfaces.hasMoreElements()) {
                        NetworkInterface ni = netInterfaces.nextElement();
                        String name = ni.getName();
                        Enumeration<InetAddress> ips = ni.getInetAddresses();
                        while (ips.hasMoreElements()) {
                            String Ip = ((InetAddress) ips.nextElement()).getHostAddress();
                            if (!"127.0.0.1".equals(Ip) && ("eth0".equalsIgnoreCase(name) || "eth1"
                                    .equalsIgnoreCase(name)) && Ip.indexOf(":") == -1) {
                                localIp = Ip;
                                break;
                            }
                        }
                    }
                } catch (Exception e) {
                }
            } else {
                localIp = InetAddress.getLocalHost().getHostAddress();
            }
        } catch (UnknownHostException e) {
            return "127.0.0.1";
        }
        return localIp;
    }

}
